﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RouterControl.Db;
using UPNP.IO;

internal static class DeviceDomExtensionMethods
{
	public static DeviceDomDb ToDeviceDomDb(this DeviceDom dom)
	{
		// handle root element
		var db = new DeviceDomDb();

		db.SchemaId = dom.SchemaId;
        db.Version = DeviceSchema.SchemaVersion;
		db.DomType = DeviceDomTypeDb.UserDevice;

		db.RootDevice = dom.RootDevice.ToDeviceDomDb();

		// finalize
		return db;
	}

	private static DeviceDb ToDeviceDomDb(this DeviceDom.Device dev)
	{
		// the device
		var db = new DeviceDb();

		db.DeviceName = dev.DeviceName;
		db.DeviceTypeId = dev.DeviceTypeId;
		db.IsOptional = false;
		db.IsRootDevice = (dev.ParentDevice == null);

		// services
		foreach (var s in dev.Services)
		{
			db.Services.Add(s.ToDeviceDomDb());
		}

		// child devices
		foreach (var c in dev.ChildDevices)
		{
			db.ChildDevices.Add(c.ToDeviceDomDb());
		}

		// finalize
		return db;
	}

	private static ServiceDb ToDeviceDomDb(this DeviceDom.Service serv)
	{
		// the service
		var db = new ServiceDb();

		db.ServiceName = serv.ServiceName;
		db.ServiceTypeId = serv.ServiceTypeId;

		// add the state variables
		foreach (var sv in serv.StateVariables)
		{
			var t = new StateVariableDb();

			t.VariableName = sv.VariableName;
			t.DataTypeName = sv.DataTypeName;
			t.IsOptional = false;
			t.SendEventsAttribute = sv.SendEvents;

			// allowed values
			if (sv.AllowedValues != null)
			{
				foreach (var av in sv.AllowedValues)
				{
					t.AllowedValues.Add(new AllowedValueDb()
					{
						Value = av
					});
				}
			}

			db.StateVariables.Add(t);
		}

		// add the actions
		foreach (var act in serv.Actions)
		{
			var a = new ActionDb();

			a.ActionName = act.ActionName;

			// arguments
			var argPos = 0;

			foreach (var arg in act.Arguments)
			{
				var aa = new ActionArgumentDb();

				aa.ArgumentName = arg.ArgumentName;
				aa.DirectionIsOut = (arg.Direction == DeviceDom.ActionParameterDirection.Out);
				aa.ArgumentOrder = (++argPos);

				aa.RelatedStateVariable = (from sv in db.StateVariables
											where sv.VariableName == arg.RelatedVariable.VariableName
											select sv).Take(1).First();

				a.Arguments.Add(aa);
			}

			db.Actions.Add(a);
		}

		// finalize
		return db;
	}

}
